package Controllers;

import Entities.Advantages.*;
import Entities.Ball;
import Entities.Bar;
import Entities.BarSize;
import Entities.Missile;
import Entities.Phase;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AdvantageController extends Thread {

    private Phase phase;
    private int missiles = 0;
    private boolean stop;
    private ArrayList<IAdvantage> advantageList;
    private Bar bar;
    private ArrayList<Ball> ballList;

    public AdvantageController(Phase phase) {
        this.phase = phase;
        stop = false;
        advantageList = new ArrayList<>();
    }

    private void applyAdvantage(DecreaseBallSpeed decreaseBallSpeed) {
        synchronized (ballList) {
            for (Ball b : ballList) {
                try {
                    if (Math.abs(b.getMaxDy()) != 1) {
                        double oldDx = b.getMaxDx();
                        if (b.getDx() > 0) {
                            b.setMaxDx(1);
                            b.setDx((b.getDx() * b.getMaxDx()) / oldDx);
                        } else {
                            b.setMaxDx(1);
                            b.setDx((b.getDx() * b.getMaxDx()) / oldDx);
                        }
                        double oldDy = b.getMaxDy();
                        if (b.getDy() > 0) {
                            b.setMaxDy(1);
                            b.setDy(((b.getDy() * b.getMaxDy()) / oldDy));
                        } else if (b.getDy() < 0) {
                            b.setMaxDy(1);
                            b.setDy(((b.getDy() * b.getMaxDy()) / oldDy));
                        }
                    }
                } catch (Exception e) {
                    Logger.getLogger(AnimationController.class.getName()).log(Level.SEVERE, null, e);
                    System.out.println(e.getCause());
                }
            }
        }
    }

    private void applyAdvantage(IncreaseBallSpeed increaseBallSpeed) {
        synchronized (ballList) {
            for (Ball b : ballList) {
                double oldDx = b.getMaxDx();
                if (b.getDx() > 0) {
                    b.setMaxDx(2);
                    b.setDx((b.getDx() * b.getMaxDx()) / oldDx);
                } else {
                    b.setMaxDx(2);
                    b.setDx((b.getDx() * b.getMaxDx()) / oldDx);
                }
                if (b.getDy() > 0) {
                    b.setMaxDy(2);
                    b.setDy((float) 2);
                } else {
                    b.setMaxDy(2);
                    b.setDy((float) -2);
                }
            }
        }
    }

    private void applyAdvantage(DecreaseBarSize decreaseBarSize) {
        synchronized (bar) {
            bar.setSize(BarSize.SMALL);
        }
    }

    private void applyAdvantage(IncreaseBarSize increaseBarSize) {
        synchronized (bar) {
            bar.setSize(BarSize.HIGH);
        }
    }

    private void applyAdvantage(MissileAdvantage missileAdvantage) {
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                synchronized (bar) {
                    Missile missile = new Missile(bar.getX() + bar.getWidth() / 2, 0);
                    missile.setY(bar.getY() - missile.getHeight() - 2);
                    missile.setDy(1);
                    synchronized (phase) {
                        phase.addChild(missile);
                    }
                    missiles++;
                }
            }
        };

        Timer timer = new Timer();
        timer.scheduleAtFixedRate(timerTask, 0, 500);
    }

    private void applyAdvantage(ThreeBallsAdvantage threeBallsAdvantage) {
        double x = ballList.get(0).getX();
        double y = ballList.get(0).getY();
        Ball b1 = new Ball(x, y, 1, -1, 8);
        Ball b2 = new Ball(x, y, -1, -1, 8);
        synchronized (phase) {
            phase.addChild(b1);
            phase.addChild(b2);
        }
        synchronized (ballList) {
            ballList.add(b1);
            ballList.add(b2);
        }
    }

    private void unApplyAdvantage(MissileAdvantage missileAdvantage) {
    }

    private void unApplyAdvantage(ThreeBallsAdvantage threeBallsAdvantage) {
    }

    private void applyAdvantage(IAdvantage iAdvantage) {
        //TODO: hacer con reflection
        if (iAdvantage instanceof DecreaseBallSpeed) {
            applyAdvantage((DecreaseBallSpeed) iAdvantage);
        } else if (iAdvantage instanceof DecreaseBarSize) {
            applyAdvantage((DecreaseBarSize) iAdvantage);
        } else if (iAdvantage instanceof IncreaseBallSpeed) {
            applyAdvantage((IncreaseBallSpeed) iAdvantage);
        } else if (iAdvantage instanceof IncreaseBarSize) {
            applyAdvantage((IncreaseBarSize) iAdvantage);
        } else if (iAdvantage instanceof MissileAdvantage) {
            applyAdvantage((MissileAdvantage) iAdvantage);
        } else if (iAdvantage instanceof ThreeBallsAdvantage) {
            applyAdvantage((ThreeBallsAdvantage) iAdvantage);
        }
    }

    private void unApplyAdvantage(DecreaseBallSpeed decreaseBallSpeed) {
    }

    private void unApplyAdvantage(IncreaseBallSpeed increaseBallSpeed) {
    }

    private void unApplyAdvantage(DecreaseBarSize decreaseBarSize) {
        synchronized (bar) {
            //bar.setSize(BarSize.NORMAL);
        }
    }

    private void unApplyAdvantage(IncreaseBarSize increaseBarSize) {
        synchronized (bar) {
            //bar.setSize(BarSize.NORMAL);
        }
    }

    private void unApplyAdvantage(IAdvantage iAdvantage) {
        if (iAdvantage instanceof DecreaseBallSpeed) {
            unApplyAdvantage((DecreaseBallSpeed) iAdvantage);
        } else if (iAdvantage instanceof DecreaseBarSize) {
            unApplyAdvantage((DecreaseBarSize) iAdvantage);
        } else if (iAdvantage instanceof IncreaseBallSpeed) {
            unApplyAdvantage((IncreaseBallSpeed) iAdvantage);
        } else if (iAdvantage instanceof IncreaseBarSize) {
            unApplyAdvantage((IncreaseBarSize) iAdvantage);
        } else if (iAdvantage instanceof MissileAdvantage) {
            unApplyAdvantage((MissileAdvantage) iAdvantage);
        } else if (iAdvantage instanceof ThreeBallsAdvantage) {
            unApplyAdvantage((ThreeBallsAdvantage) iAdvantage);
        }
    }

    @Override
    public void run() {
        while (!stop) {
            synchronized (advantageList) {
                IAdvantage advantage = null;
                for (IAdvantage iAdvantage : advantageList) {
                    //TODO: comprobación de tiempo errónea
                    if (iAdvantage.getStartTime() + iAdvantage.getDuration() < System.currentTimeMillis()) {
                        advantage = iAdvantage;
                    }
                    //TimeUnit.MILLISECONDS.
                }
                if (advantage != null) {
                    unApplyAdvantage(advantage);
                    advantageList.remove(advantage);
                }
            }
        }
    }

    public void setStop(boolean stop) {
        this.stop = stop;
    }

    public void addAdvantage(IAdvantage iAdvantage) {
        synchronized (advantageList) {
            advantageList.add(iAdvantage);
            applyAdvantage(iAdvantage);
        }
    }

    public void setBar(Bar bar) {
        this.bar = bar;
    }

    public void setBallList(ArrayList<Ball> ballList) {
        this.ballList = ballList;
    }
}
